﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Spotless.Services
{
        public interface IPagedList
        {
            int TotalCount
            {
                get;
            }

            int PageIndex
            {
                get;
            }

            int PageSize
            {
                get;
            }

            bool HasPreviousPage
            {
                get;
            }

            bool HasNextPage
            {
                get;
            }

            int TotalPageCount
            {
                get;
            }

            int Count
            {
                get;
            }
        }

        public class PagedList<T> : List<T>, IPagedList
        {
            public PagedList(IQueryable<T> source, int index, int pageSize)
            {
                this.TotalCount = source.Count();
                this.PageSize = pageSize;
                this.PageIndex = index;
                if (index > TotalCount / pageSize)
                {
                    PageIndex = TotalCount / pageSize;
                }
                this.AddRange(source.Skip(PageIndex * pageSize).Take(pageSize).ToList());
            }

            public PagedList(IEnumerable<T> source, int index, int pageSize)
            {
                this.TotalCount = source.Count();
                this.PageSize = pageSize;
                this.PageIndex = index;
                if (index > TotalCount / pageSize)
                {
                    PageIndex = TotalCount / pageSize;
                }
                this.AddRange(source.Skip(index * pageSize).Take(pageSize).ToList());
            }

            public PagedList(IEnumerable<T> source, int index, int pageSize, int totalCount)
            {
                this.TotalCount = totalCount;
                this.PageSize = pageSize;
                this.PageIndex = index;
                if (index > TotalCount / pageSize)
                {
                    PageIndex = TotalCount / pageSize;
                }
                this.AddRange(source);
            }

            public int TotalCount
            {
                get;
                private set;
            }

            public int TotalPageCount
            {
                get
                {
                    return (int)Math.Ceiling((float)TotalCount / (float)PageSize);
                }
            }

            public int PageIndex
            {
                get;
                private set;
            }

            public int PageSize
            {
                get;
                private set;
            }

            public bool HasPreviousPage
            {
                get
                {
                    return (PageIndex > 0);
                }
            }

            public bool HasNextPage
            {
                get
                {
                    return (PageIndex + 1) * PageSize <= TotalCount;
                }
            }

            public int PagedIndexOf(T item)
            {
                return this.IndexOf(item) + (this.PageSize * this.PageIndex);
            }
        }

        public static class Pagination
        {
            public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index, int pageSize)
            {
                return new PagedList<T>(source, index, pageSize);
            }

            public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index)
            {
                return new PagedList<T>(source, index, 10);
            }

            public static PagedList<T> ToPagedList<T>(this IEnumerable<T> source, int index, int pageSize)
            {
                return new PagedList<T>(source, index, pageSize);
            }

            public static PagedList<T> ToPagedList<T>(this IEnumerable<T> source, int index)
            {
                return new PagedList<T>(source, index, 10);
            }
        }
    }
